package com.mcxx.modules.miniSalvation.family.service.write;

import cn.hutool.core.util.IdUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.PropertiesConstant;
import com.mcxx.ansync.event.PropertiesEventHandler;
import com.mcxx.modules.filemanage.file.service.impl.FileServiceImpl;
import com.mcxx.modules.miniSalvation.family.dao.read.FamilyThreeMemberDao;
import com.mcxx.modules.miniSalvation.family.dao.write.FamilyMainWriteDao;
import com.mcxx.modules.miniSalvation.family.dto.ApplyRtnDTO;
import com.mcxx.modules.miniSalvation.family.dto.FamilyMemberDTO;
import com.mcxx.modules.miniSalvation.family.dto.FamilyThreeMemberDTO;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMainEntity;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMemberEntity;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberReadService;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service("familyMainWriteService")
@TaTransactional
@EnableAsync
public class FamilyMainWriteService {
    @Resource
    private FamilyMainWriteDao familyMainWriteDao;
    @Autowired
    private FamilyMemberReadService familyMemberReadService;
    @Autowired
    private FamilyMemberWriteService familyMemberWriteService;
    @Autowired
    private PropertiesEventHandler propertiesEventHandler;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private FamilyThreeMemberDao familyThreeMemberDao;

    private static final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);

    
    public int addFamily(FamilyMainEntity familyMain) {
        return familyMainWriteDao.insertIgnoreNull(familyMain);
    }

    
    public int updateFamily(FamilyMainEntity familyMain) {
        
        propertiesEventHandler.publishChangeEvent(familyMain, PropertiesConstant.CATE_FAMILY_CHANGE, null);
        return familyMainWriteDao.updateIgnoreNull(familyMain);
    }

    
    public ApplyRtnDTO addFamilyAndMember4Apply(FamilyMainEntity family, FamilyMemberEntity member, String memberOldState, UserAccountVo userAccountVo, String orderType) {
        logger.info("低保申请，新增家庭和成员记录，参数是：{}", member);
        ApplyRtnDTO rtnDTO = new ApplyRtnDTO();

        
        Map<String,String> touple = familyMemberReadService.getMemberIdAndFamilyIdByIdCard(member.getIdcard());
        String existedFamilyId = "", existedMemberId = "", memberState = "";
        
        if (!CommonUtil.invalidArgs(touple)) {
            logger.info("到根据身份证号查询的memberId和familyId，结果是：{}", touple);
            
            existedFamilyId = Constant.PeopleState.MOVE_OUT_HOUSEHOLD.equals(memberOldState) ? "" : touple.get("familyId");
            existedMemberId = touple.get("memberId");
            
            memberState = touple.get("memberState");
            
            if(orderType.equals(Constant.OrderType.RECHECK)){
                member.setState(memberState);
            }
        }

        
        if (CommonUtil.invalidArgs(existedFamilyId)) {
            
            family.setId(IdUtil.simpleUUID());
            family.setFamilyRevenue(0D);
            addFamily(family);
            logger.info("新增家庭信息，参数是：{}", family);
        } else {
            
            family.setId(existedFamilyId);
            updateFamily(family);
            logger.info("更新家庭信息，参数是：{}", family);
        }
        
        FamilyThreeMemberDTO familyThreeMemberDTO  = familyThreeMemberDao.queryMemberByCardId(member.getIdcard());
        if(!CommonUtil.invalidArgs(familyThreeMemberDTO)){
            member.setHelpPoorFlag("1");
            member.setRuralObjectType(familyThreeMemberDTO.getRuralObjectType());
        }
        
        member.setFamilyId(family.getId());
        if (CommonUtil.invalidArgs(existedMemberId)) {
            
            member.setId(IdUtil.simpleUUID());
            familyMemberWriteService.insertFamilyMember(member, userAccountVo);
            logger.info("新增成员信息，参数是：{}", member);
        } else {
            
            member.setId(existedMemberId);
            member.setIsApply("1");
            familyMemberWriteService.updateFamilyMember(member);
            logger.info("更新成员信息，参数是：{}", member);
        }

        
        List<FamilyMemberEntity> memberLists = familyMemberReadService.listNormalMemberByFamilyId(family.getId());
        if(memberLists!=null && member.getAreaCode()!=null) {
            for (FamilyMemberEntity memberEntity:memberLists) {
                memberEntity.setAreaCode(member.getAreaCode());
                familyMemberWriteService.updateFamilyMember(memberEntity);
                logger.info("更新申请人-成员信息所属区域，参数是：{}", memberEntity);
            }
        }

        
        if(!CommonUtil.invalidArgs(memberState) && Constant.PeopleState.EXPIRE.equals(memberState)){
            familyMemberWriteService.updateFamilyRelationForExpire(member.getFamilyId(), member.getIdcard());
        }
        
        if(Constant.PeopleState.EXPIRE.equals(memberOldState)){
            
            family.setSaveMemberNumber(0);
            updateFamily(family);
            familyMemberWriteService.updateNoSave(existedFamilyId);
        }

        
        rtnDTO.setFamilyId(family.getId());
        rtnDTO.setMemberId(member.getId());

        return rtnDTO;
    }


    
    public void updateFamilyInfo(FamilyMemberDTO familyMemberDTO, UserAccountVo accountVo, Map<String,Integer> countMap) {
        FamilyMainEntity familyMainEntity = new FamilyMainEntity();
        familyMainEntity.setId(familyMemberDTO.getFamilyId());
        familyMainEntity.setOrgId(accountVo.getOrgId());
        familyMainEntity.setFamilyNumber(countMap.get("memberCount"));
        familyMainEntity.setSaveMemberNumber(countMap.get("saveMemberCount"));
        if(Constant.DomesticRelation.ONESELF.equals(familyMemberDTO.getFamilyRelation())){
            
            if(!Constant.PeopleState.NORMAL.equals(familyMemberDTO.getState())){
                familyMainEntity.setMasterInSave(Constant.MasterInSave.NO);
            }else{
                
                familyMainEntity.setMasterInSave(Constant.IsSaveObject.NO.equals(familyMemberDTO.getIsSaveObject()) ? Constant.MasterInSave.NO : Constant.MasterInSave.YES);
            }
            familyMainEntity.setName(familyMemberDTO.getName());
            familyMainEntity.setIdcard(familyMemberDTO.getIdcard());
        }
        int rst = this.updateFamily(familyMainEntity);
        if(rst <= 0){
            throw new BizException(FailureCode.ERR_9999);
        }
    }

    
    public int changeSaveMemberById(FamilyMainEntity familyMain){
        return familyMainWriteDao.changeSaveMemberById(familyMain);
    }

    
    public int changeSaveMemberNumById(FamilyMainEntity familyMain){
        return familyMainWriteDao.changeSaveMemberNumById(familyMain);
    }

    
   public int updateSalvationNo(String orderId,String salvationNo){
        return familyMainWriteDao.updateSalvationNo(orderId,salvationNo);
   }



    
    public int updateMainByMainHistory(String familyId, String orderId){
        return familyMainWriteDao.updateMainByMainHistory(familyId, orderId);
    }
    
    public void copyFamilyMainSource(String familyId) {
        familyMainWriteDao.copyFamilyMainSource(familyId);
    }
    
    public void updateLowerStatus(String familyId,String status) {
        familyMainWriteDao.updateLowerStatus(familyId,status);
    }
    
    public void deleteFamilyMainById(String familyId) {
        familyMainWriteDao.deleteFamilyMainById(familyId);
    }

    
    public int updateLowerFamily(FamilyMainEntity familyMainEntity){
        return familyMainWriteDao.updateLowerFamily(familyMainEntity);
    }
}
